12 Pandas 数据框拼接
12.1 引言数据整合的必要性
在实际金融分析中,数据往往分散在多个文件或数据源中: - 不同时期的数据分开存储 - 不同市场的数据分别管理 - 不同频率的数据需要整合
Pandas提供了强大的数据拼接工具,使得数据整合变得简单高效。
12.2 concat轴向拼接
pd.concat()函数用于沿指定轴拼接多个数据框。
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import pandas as pd # 导入Pandas数据分析库
# 从Excel文件读取数据存入df_price
df_price=pd.read_excel('https://huoran.oss-cn-shenzhen.aliyuncs.com/20230306/xlsx/1632680830600503296.xlsx',index_col=0,sheet_name='Sheet1')
#df1 包含前 100 行,df2 包含剩余的行
df1=df_price.iloc[:100,:]
df2=df_price.iloc[100:,:] # 按位置索引提取从Excel文件读取数据存入df_price
# 从Excel文件读取数据存入tencent_vol
tencent_vol=pd.read_excel('https://huoran.oss-cn-shenzhen.aliyuncs.com/20230306/xlsx/1632680830600503296.xlsx',index_col=0,sheet_name='Sheet2')
df_concat=pd.concat([df1,df2],axis=0) # 拼接数据框并存入df_concat
print(f'2022年有{df_concat.shape[0]}条交易数据') # 输出2022年有
# 合并数据框并存入df_merge
df_merge=pd.merge(left=df_price['腾讯控股'],right=tencent_vol,right_index=True,left_index=True)
stock_data=df_merge.loc['2022-06-01',:] # 按标签索引提取数据
print(f"这个交易日的收盘价为{stock_data[0]}元,成交量为{stock_data[2]/10000}万股") # 输出这个交易日的收盘价为concat参数详解: - objs: 要拼接的数据框列表 - axis: 0=垂直拼接(行), 1=水平拼接(列) - join: ‘inner’(交集), ‘outer’(并集,默认) - ignore_index: 是否忽略原索引重新编号 - keys: 创建层次化索引标识来源
12.3 merge数据库风格连接
pd.merge()类似于SQL的JOIN操作,基于共同列或索引合并数据。
# =============================================================================
# 题目:merge函数基于索引合并价格与成交量数据
# =============================================================================
# 在金融分析中,经常需要将不同数据表的信息整合在一起,例如将股价数据与
# 成交量数据合并,以便进行量价分析。本示例演示如何使用pd.merge()函数
# 基于日期索引将腾讯控股的收盘价和成交量数据进行内连接合并。
# ==================== 定义数据来源URL ====================
url = 'https://huoran.oss-cn-shenzhen.aliyuncs.com/20230306/xlsx/1632680830600503296.xlsx' # 与上方代码块使用相同的Excel文件地址
# ==================== 读取成交量数据 ====================
# 从同一Excel文件的Sheet2读取成交量数据
tencent_vol = pd.read_excel(url, index_col=0, sheet_name='Sheet2')
# ==================== 基于索引进行内连接合并 ====================
# pd.merge()实现类似SQL的JOIN操作:
# left:左表,取df_price中的'腾讯控股'列(收盘价)
# right:右表,取tencent_vol(成交量数据)
# left_index=True/right_index=True:使用左右两表的索引(日期)作为连接键
# how='inner':内连接,只保留两个表中索引都存在的日期
df_merge = pd.merge(
left=df_price['腾讯控股'], # 左表:腾讯控股收盘价序列
right=tencent_vol, # 右表:成交量数据
left_index=True, # 布尔值,指定使用左表的索引作为连接键
right_index=True, # 布尔值,指定使用右表的索引作为连接键
how='inner' # 连接方式,'inner'表示只保留匹配的行
)
# ==================== 输出合并后的数据 ====================
print("合并后的数据:") # 打印标题
print(df_merge.head()) # 显示前5行数据,包含收盘价和成交量
# ==================== 查询特定日期的交易数据 ====================
# 使用.loc通过日期索引定位特定行的数据
stock_data = df_merge.loc['2022-06-01', :] # 获取2022-06-01这一行的所有列数据
print(f"\n2022-06-01的交易数据:") # 打印日期标题
print(f" 收盘价: {stock_data[0]:.2f}元") # 输出收盘价,保留2位小数
print(f" 成交量: {stock_data[2]/10000:.2f}万股") # 输出成交量,转换为万股单位merge参数详解: - left, right: 要合并的两个数据框 - how: 连接方式 - 'inner': 内连接(交集,默认) - 'outer': 外连接(并集) - 'left': 左连接(保留左表所有行) - 'right': 右连接(保留右表所有行) - on: 用于连接的列名 - left_on, right_on: 左右表不同的列名
12.4 join索引合并
join()是merge的简化版,专门用于基于索引合并。
# =============================================================================
# 题目:join函数简化索引合并操作
# =============================================================================
# join()是merge()的便捷方法,专门用于基于索引合并数据框,语法更加简洁。
# 本示例演示如何使用join()方法将腾讯控股的收盘价与成交量数据合并,
# 相比merge(),join()更适合处理基于索引的合并场景。
# ==================== 使用join进行索引合并 ====================
# df_price[['腾讯控股']]:从价格数据框中提取'腾讯控股'列
# .join(tencent_vol):将成交量数据框基于索引合并到收盘价数据框
# how='inner':内连接,只保留两个表中索引都存在的日期
df_join = df_price[['腾讯控股']].join( # 调用左表的join方法
tencent_vol, # 要合并的右表(成交量数据)
how='inner' # 连接方式,内连接保留匹配的索引
)
# ==================== 输出合并结果 ====================
print("使用join合并:") # 打印提示信息
print(df_join.head()) # 显示前5行数据,包含收盘价和成交量12.5 拼接的金融应用场景
12.5.1 1. 多时期数据整合
# =============================================================================
# 题目:concat拼接不同月份的股价数据
# =============================================================================
# 在金融时间序列分析中,经常需要将不同时期的数据(如月度数据、季度数据)
# 拼接成更长时间序列以便进行趋势分析。本示例演示如何使用concat()将1月
# 和2月的股价数据垂直拼接成Q1(第一季度)完整数据。
# ==================== 创建1月数据 ====================
# 使用字典创建DataFrame,包含价格和成交量两列
jan_data = pd.DataFrame({
'price': [10, 11, 12], # 股价数据,表示3个交易日的收盘价
'volume': [1000, 1100, 1200] # 成交量数据,单位可能是手或股
}, index=pd.date_range('2024-01-01', periods=3)) # 创建日期范围索引,从2024-01-01开始的3天
# ==================== 创建2月数据 ====================
# 创建2月的交易数据,结构相同
feb_data = pd.DataFrame({
'price': [13, 14, 15], # 2月的股价数据,显示上升趋势
'volume': [1300, 1400, 1500] # 2月的成交量,呈现增长态势
}, index=pd.date_range('2024-02-01', periods=3)) # 2月日期索引
# ==================== 垂直拼接两月数据 ====================
# pd.concat()默认axis=0,将feb_data追加到jan_data下方
# 拼接后形成包含1月和2月数据的Q1时间序列
q1_data = pd.concat([jan_data, feb_data]) # 垂直拼接,自动对齐列名
print("Q1数据:") # 打印标题
print(q1_data) # 输出完整的Q1数据,包含6个交易日12.5.2 2. 多市场数据整合
# =============================================================================
# 题目:concat拼接沪市和深市的股票数据
# =============================================================================
# 在A股市场中,股票分为上海证券交易所(沪市)和深圳证券交易所(深市)。
# 实际分析中常需要将两个市场的数据整合在一起进行跨市场比较分析。
# 本示例演示如何使用concat()的keys参数为拼接后的数据添加层次化索引,
# 标识每条数据来源于哪个市场。
# ==================== 创建沪市股票数据 ====================
# 构造包含股票代码、名称和价格的DataFrame
sh_data = pd.DataFrame({
'code': ['600000.SH', '600036.SH'], # 股票代码,.SH后缀表示沪市
'name': ['浦发银行', '招商银行'], # 股票名称
'price': [10.5, 45.2] # 股价,单位为元
})
# ==================== 创建深市股票数据 ====================
# 构造深市股票数据,结构与沪市相同
sz_data = pd.DataFrame({
'code': ['000001.SZ', '000002.SZ'], # 股票代码,.SZ后缀表示深市
'name': ['平安银行', '万科A'], # 股票名称
'price': [12.3, 8.5] # 股价,单位为元
})
# ==================== 垂直拼接并添加市场标识 ====================
# pd.concat()的keys参数为拼接后的数据创建层次化索引
# keys=['沪市', '深市']:为两个数据框分别添加标签
# names=['市场']:指定层次化索引的级别名称
all_stocks = pd.concat([sh_data, sz_data], keys=['沪市', '深市'], names=['市场'])
print("两市股票:") # 打印标题
print(all_stocks) # 输出包含市场标识的合并数据,可通过层次化索引区分市场